package game.Weapons;

import game.Audio.AudioResources;
import game.Sprites.Transparency;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;

import javax.imageio.ImageIO;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class Weapon_info implements Cloneable {
    int code;               // Id code of weapon
    String name;            // String name of weapon
    String display_name;    // Display name of weapon
    int recoil_accuracy;    // Accuray while shooting
    int recoil_recover;     // Recover of shooting
    int recoil_attack;      // Attack recoil
    int firedelay;          // Fire delay
    int price;              // Price of weapon in store
    int damage;             // Damage caused
    int ammo_charger;       // Number of bullets in the charger
    int ammo_total;         // Number of total bullets
    int range;              // Shooting range
    double weight;          // Weight of weapon (influences player speed)
    boolean primary;        // True if primary weapon, false if secondary weapon
    int type;               // 0 handgun, 1 shotgun, 2 subMachinegun, 3 rifle, 4 machinegun
    int team;               // 0 both, 1 only terrorist, 2 only counter-terrorist

    public int ammo_charger_value;  // Constant value of ammo_charger
    public int ammo_total_value;    // Constant value of ammo_total

    Image image;        // Weapon sprite
    Image shopImage;    // Shop sprite
    Image shopImage2;   // Shop sprite 2

    Clip soundClip;


    /**
     * Constructor of Weapon_info
     * @param code
     * @param name
     * @param recoil_accuracy
     * @param recoil_recover
     * @param recoil_attack
     * @param firedelay
     * @param price
     * @param damage
     * @param ammo_charger
     * @param ammo_total
     * @param range
     * @param weight
     * @param primary
     */
    public Weapon_info(int code, String name, String display_name, int recoil_accuracy, int recoil_recover, int recoil_attack,
                       int firedelay, int price, int damage, int ammo_charger, int ammo_total,
                       int range, double weight, boolean primary, int type, int team) throws IOException, LineUnavailableException, UnsupportedAudioFileException {
        this.code = code;
        this.name = name;
        this.display_name = display_name;
        this.recoil_accuracy = recoil_accuracy;
        this.recoil_recover = recoil_recover;
        this.recoil_attack = recoil_attack;
        this.firedelay = firedelay;
        this.price = price;
        this.damage = damage;
        this.ammo_charger = ammo_charger;
        this.ammo_charger_value = ammo_charger;
        this.ammo_total = ammo_total;
        this.ammo_total_value = ammo_total;
        this.range = range;
        this.weight = weight;
        this.primary = primary;
        this.type = type;
        this.team = team;

        // Find images
        String path="", path2="";
        if(this.type != 6) {
            path = "Sprites/Weapons/"+name+".bmp";
            path2 = "Sprites/Weapons/"+name+"_k.bmp";
        }

        String path3 = "Sprites/Weapons/"+name+"_m.bmp";
        try {
            if(this.type != 6) {
                this.image = SwingFXUtils.toFXImage(Transparency.loadTransparentBMP(Weapon_info.class.getClassLoader().getResourceAsStream(path)), null);
                this.shopImage = SwingFXUtils.toFXImage(Transparency.loadTransparentBMP(Weapon_info.class.getClassLoader().getResourceAsStream(path2)), null);
            }
            else {
                this.shopImage = SwingFXUtils.toFXImage(Transparency.loadTransparentBMP(Weapon_info.class.getClassLoader().getResourceAsStream("Sprites/Weapons/"+name+"_k.bmp")), null);
            }
           if(code != 50) {
                this.shopImage2 = SwingFXUtils.toFXImage(Transparency.loadTransparentBMP(Weapon_info.class.getClassLoader().getResourceAsStream(path3)), null);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Find audio stream
        path = "audio/weapons/"+name+".wav";
        if(name.contains("knife"))
            path = "audio/weapons/"+name+"_slash.wav";

        //System.out.println(path);
        if(this.code != 56) {
            this.soundClip = AudioResources.loadClip(path);
        }
    }

    public void getDefault() {
        this.ammo_charger = this.ammo_charger_value;
        this.ammo_total = this.ammo_total_value;
    }


    public void shoot() {
        this.ammo_charger -= 1;
    }

    public void reload(int v) {
        this.ammo_total -= v;
    }

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    /**
     * GETTERS & SETTERS
     */

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public String getDisplayName() {
        return display_name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getRecoil_accuracy() {
        return recoil_accuracy;
    }

    public void setRecoil_accuracy(int recoil_accuracy) {
        this.recoil_accuracy = recoil_accuracy;
    }

    public int getRecoil_recover() {
        return recoil_recover;
    }

    public void setRecoil_recover(int recoil_recover) {
        this.recoil_recover = recoil_recover;
    }

    public int getRecoil_attack() {
        return recoil_attack;
    }

    public void setRecoil_attack(int recoil_attack) {
        this.recoil_attack = recoil_attack;
    }

    public int getFiredelay() {
        return firedelay;
    }

    public void setFiredelay(int firedelay) {
        this.firedelay = firedelay;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public int getDamage() {
        return damage;
    }

    public void setDamage(int damage) {
        this.damage = damage;
    }

    public int getAmmo_charger() {
        return ammo_charger;
    }

    public void setAmmo_charger(int ammo_charger) {
        this.ammo_charger = ammo_charger;
    }

    public int getAmmo_total() {
        return ammo_total;
    }

    public void setAmmo_total(int ammo_total) {
        this.ammo_total = ammo_total;
    }

    public int getRange() {
        return range;
    }

    public void setRange(int range) {
        this.range = range;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public boolean isPrimary() {
        return primary;
    }

    public void setPrimary(boolean primary) {
        this.primary = primary;
    }

    public int getType() { return type; }

    public void setType(int type) {
        this.type = type;
    }

    public int getTeam() { return team; }

    public void setTeam(int team) {
        this.team = team;
    }

    public double getReloadTime(){
        return 1.0;
    }

    public Image getPlayerImage() {
        return image;
    }

    public Image getShopImage() {
        return shopImage;
    }

    public Image getShopImage2() {
        return shopImage2;
    }


    public Clip getShotAudio() {
        return soundClip;
        //return iStream;
    }
}
